export default class Vector2 {
  x: number;
  y: number;
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
  set(x: Vector2['x'], y: Vector2['y']) {
    this.x = x;
    this.y = y;
  }
  setX(x: Vector2['x']) {
    this.x = x;
    return this;
  }
  setY(y: Vector2['y']) {
    this.y = y;
    return this;
  }
  // 拷贝
  copy(v2: Vector2) {
    this.x = v2.x;
    this.y = v2.y;
  }
  // 克隆
  clone() {
    return new Vector2(this.x, this.y);
  }
  // 减法
  sub(v: Vector2): this {
    this.x -= v.x;
    this.y -= v.y;
    return this;
  }
  // 加法
  add(v: Vector2): this {
    this.x += v.x;
    this.y += v.y;

    return this;
  }
  subVectors(a: Vector2, b: Vector2) {
    this.x = a.x - b.x;
    this.y = a.y - b.y;

    return this;
  }
  addVectors(a: Vector2, b: Vector2) {
    this.x = a.x + b.x;
    this.y = a.y + b.y;

    return this;
  }
  addScalar(s: number) {
    this.x += s;
    this.y += s;

    return this;
  }
  lengthSq() {
    return this.x * this.x + this.y * this.y;
  }
  dot(v: Vector2) {
    return this.x * v.x + this.y * v.y;
  }

  angleTo(v: Vector2) {
    const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());

    if (denominator === 0) return Math.PI / 2;

    const theta = this.dot(v) / denominator;

    // clamp, to handle numerical problems

    return Math.acos(theta);
  }
  angle() {
    // computes the angle in radians with respect to the positive x-axis

    const angle = Math.atan2(-this.y, -this.x) + Math.PI;

    return angle;
  }
  distanceTo(v: Vector2) {
    return Math.sqrt(this.distanceToSquared(v));
  }
  length() {
    return Math.sqrt(this.x * this.x + this.y * this.y);
  }
  normalize() {
    return this.divideScalar(this.length() || 1);
  }
  divideScalar(scalar: number) {
    return this.multiplyScalar(1 / scalar);
  }
  multiplyScalar(scalar: number) {
    this.x *= scalar;
    this.y *= scalar;

    return this;
  }
  distanceToSquared(v: Vector2) {
    const dx = this.x - v.x,
      dy = this.y - v.y;
    return dx * dx + dy * dy;
  }
}
